package com.techsoul.module.accounting.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.techsoul.common.core.exception.BusinessException;
import com.techsoul.common.core.exception.ParamException;
import com.techsoul.common.core.pojo.vo.UserVo;
import com.techsoul.common.core.util.ServletUtils;
import com.techsoul.common.core.util.bean.BeanUtils;
import com.techsoul.common.core.util.collection.ListUtils;
import com.techsoul.common.core.util.id.IdWorker;
import com.techsoul.common.core.util.lang.DateUtils;
import com.techsoul.common.core.util.lang.NumberUtils;
import com.techsoul.common.core.util.lang.StringUtils;
import com.techsoul.common.security.service.TokenService;
import com.techsoul.module.accounting.enmus.AccountingStatusEnum;
import com.techsoul.module.accounting.enmus.DiscountActivityTypeEnum;
import com.techsoul.module.accounting.mapper.AccountingArMapper;
import com.techsoul.module.accounting.pojo.entity.AccountingAp;
import com.techsoul.module.accounting.pojo.entity.AccountingAr;
import com.techsoul.module.accounting.pojo.param.*;
import com.techsoul.module.accounting.pojo.vo.AccountingArVo;
import com.techsoul.module.accounting.pojo.vo.MaterialBuyPriceVo;
import com.techsoul.module.accounting.pojo.vo.MaterialSalesPriceVo;
import com.techsoul.module.accounting.pojo.vo.PromotionDiscountPriceVo;
import com.techsoul.module.accounting.service.IAccountingArService;
import com.techsoul.module.accounting.service.IMaterialBuyPriceService;
import com.techsoul.module.accounting.service.IMaterialSalesPriceService;
import com.techsoul.module.accounting.service.IPromotionDiscountPriceService;
import com.techsoul.module.order.enmus.SalesOrderStatusEnum;
import com.techsoul.module.order.pojo.param.SalesOrderItemSaveParam;
import com.techsoul.module.order.pojo.vo.SalesOrderItemVo;
import com.techsoul.module.order.service.ISalesOrderItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 财务应收 Service实现
 *
 * @author liuen
 * @date 2021-04-11
 */
@Service
@Transactional(readOnly = true)
public class AccountingArServiceImpl implements IAccountingArService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private AccountingArMapper mapper;

    @Autowired
    private TokenService tokenService;
    @Autowired
    private IMaterialSalesPriceService materialSalesPriceService;
    @Autowired
    private IPromotionDiscountPriceService PromotionDiscountPriceService;

    @Autowired
    private ISalesOrderItemService salesOrderItemService;
    /**
     * 新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String insert(AccountingArSaveParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        AccountingAr entity = new AccountingAr();
        BeanUtils.copyProperties(params, entity);
        entity.setId(idWorker.nextId() + "").preInsert(user.getId());
        this.mapper.insert(entity);
        return entity.getId();
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer delete(String id) {
        return this.mapper.deleteById(id);
    }

    /**
     * 批量删除
     * @param idList
     */
    @Transactional(readOnly = false)
    @Override
    public Integer batchDelete(List<String> idList) {
        if (ListUtils.isNotEmpty(idList)) {
            return this.mapper.deleteBatchIds(idList);
        } else {
            return 0;
        }
    }

    /**
     * 修改
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer update(AccountingArSaveParam params) {
        AccountingAr entityFromDb = this.mapper.selectById(params.getId());
        if (entityFromDb == null) {
            throw new ParamException("id=" + params.getId());
        }
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        BeanUtils.copyProperties(params, entityFromDb);
        entityFromDb.preUpdate(user.getId());
        return this.mapper.updateById(entityFromDb);
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public AccountingArVo findById(String id) {
        return this.mapper.findById(id);
    }

    /**
     * 列表
     * @param params
     * @return
     */
    @Override
    public List<AccountingArVo> findAll(AccountingArSearchParam params) {
        return this.mapper.findAll(params);
    }

    /**
     * 列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AccountingArVo> findAll(AccountingArSearchParam params, Integer current, Integer pageSize) {
        return this.mapper.findAll(new Page<>(current, pageSize), params);
    }
    /**
     * 产生财务结算数据
     *
     * @param salesOrderItem
     * @param materialSalesPriceSearchParam
     * @return
     */
    @Override
    public Double getSaleTotalAmount(SalesOrderItemVo salesOrderItem, MaterialSalesPriceSearchParam materialSalesPriceSearchParam) {
        materialSalesPriceSearchParam.setWholeSaleQuantity(salesOrderItem.getQty());

        List<MaterialSalesPriceVo> materialSalesPrices = materialSalesPriceService.findAll(materialSalesPriceSearchParam);
        if (materialSalesPrices != null && materialSalesPrices.size() > 0) {
            MaterialSalesPriceVo materialSalesPriceVo = materialSalesPrices.get(0);

            Double apamt = NumberUtils.mul(materialSalesPriceVo.getSettlePrice().doubleValue(),salesOrderItem.getQty());
            salesOrderItem.setStatus(SalesOrderStatusEnum.ACC_GEN.getValue());
            return apamt;
        } else {
            salesOrderItem.setGenAccFailedReason("没有普通销售费率");
            salesOrderItem.setStatus(SalesOrderStatusEnum.ACC_FAILED.getValue());
            return 0.0;
        }

    }

    /**
     * 产生搞活动财务结算数据
     *
     * @param salesOrderItem
     * @param promotionDiscountPriceSearchParam
     * @return
     */
    @Override
    public Double getSaleTotalDisctAmount(SalesOrderItemVo salesOrderItem, PromotionDiscountPriceSearchParam promotionDiscountPriceSearchParam, MaterialSalesPriceSearchParam materialSalesPriceSearchParam) {
        promotionDiscountPriceSearchParam.setWholeSaleQuantity(salesOrderItem.getQty());
        double amt = 0.0;
        List<PromotionDiscountPriceVo> promotionDiscountPrices = PromotionDiscountPriceService.findAll(promotionDiscountPriceSearchParam);
        if (promotionDiscountPrices != null && promotionDiscountPrices.size() > 0) {
            PromotionDiscountPriceVo promotionDiscountPrice = promotionDiscountPrices.get(0);
            if (!StringUtils.isNull(promotionDiscountPrice.getActivityType())) {
                if (promotionDiscountPrice.getActivityType().equals(DiscountActivityTypeEnum.BF.getStatusCode())) {
                    Integer buyqty = promotionDiscountPrice.getBuyNumber();
                    Integer freeqty = promotionDiscountPrice.getGetFree();
                    Double totalQty = NumberUtils.add(buyqty, freeqty);
                    Double paypecentage = NumberUtils.div(buyqty, totalQty);
                    Double needPayQty = NumberUtils.mul(paypecentage, salesOrderItem.getQty());
                    double needPay = Math.ceil(needPayQty);
                    amt = NumberUtils.mul(needPay, Double.valueOf(promotionDiscountPrice.getSettlePrice()).doubleValue());
                } else if (promotionDiscountPrice.getActivityType().equals(DiscountActivityTypeEnum.BP.getStatusCode())) {
                    amt = NumberUtils.mul(salesOrderItem.getQty(), Double.valueOf(promotionDiscountPrice.getSettlePrice()).doubleValue());

                } else {
                    materialSalesPriceSearchParam.setWholeSaleQuantity(salesOrderItem.getQty());
                    List<MaterialSalesPriceVo> materialSalesPriceVos = materialSalesPriceService.findAll(materialSalesPriceSearchParam);
                    if (materialSalesPriceVos != null && materialSalesPriceVos.size() > 0) {
                        if (promotionDiscountPrice.getActivityType().equals(DiscountActivityTypeEnum.PT.getStatusCode())) {
                            MaterialSalesPriceVo materialSalesPriceVo = materialSalesPriceVos.get(0);
                            BigDecimal apamt = materialSalesPriceVo.getSettlePrice();
                            amt = NumberUtils.mul(apamt.doubleValue(), promotionDiscountPrice.getPromotionDiscountRate().doubleValue());
                        } else if (promotionDiscountPrice.getActivityType().equals(DiscountActivityTypeEnum.DP.getStatusCode())) {
                            MaterialSalesPriceVo materialSalesPriceVo = materialSalesPriceVos.get(0);
                            BigDecimal apamt = materialSalesPriceVo.getSettlePrice();
                            amt = NumberUtils.sub(apamt.doubleValue(), Double.valueOf(promotionDiscountPrice.getSettlePrice()).doubleValue());
                        }
                    } //end if
                    else{
                        salesOrderItem.setGenAccFailedReason("没有普通销售费率");
                        salesOrderItem.setStatus(SalesOrderStatusEnum.ACC_FAILED.getValue());
                        return 0.0;
                    }
                } //end else
            } // end if
        }// end if
        else{
            salesOrderItem.setGenAccFailedReason("没有活动和折扣销售费率");
            salesOrderItem.setStatus(SalesOrderStatusEnum.ACC_FAILED.getValue());
            return 0.0;
        }
        salesOrderItem.setStatus(SalesOrderStatusEnum.ACC_GEN.getValue());
        return amt;
    }


    /**
     * 获得供应商付款金额
     * @param map
     *
     * @return
     */
    @Override
    public Double getCustomerArAmount(Map map, UserVo userVo){
        Double apamt = 0.0;
        String salesOrderItemNo = (String) map.get("salesOrderItemNo");
        SalesOrderItemVo salesOrderItem = salesOrderItemService.findById(salesOrderItemNo);
        MaterialSalesPriceSearchParam materialSalesPriceSearchParam = new MaterialSalesPriceSearchParam();

        if (!StringUtils.isNull(salesOrderItem.getDiscountActivityCode())) {//搞活动
            PromotionDiscountPriceSearchParam promotionDiscountPriceSearchParam
                    = new PromotionDiscountPriceSearchParam();
            if(!StringUtils.isNull(salesOrderItem.getGoodGroupId())){
                promotionDiscountPriceSearchParam.setGoodGroupId(salesOrderItem.getGoodGroupId());
                materialSalesPriceSearchParam.setGoodGroupId(salesOrderItem.getGoodGroupId());
            }else if(!StringUtils.isNull(salesOrderItem.getSkuId())){
                promotionDiscountPriceSearchParam.setSkuId(salesOrderItem.getSkuId());
                materialSalesPriceSearchParam.setSkuId(salesOrderItem.getSkuId());
            }else {
                promotionDiscountPriceSearchParam.setSpuId(salesOrderItem.getSpuId());
                materialSalesPriceSearchParam.setSpuId(salesOrderItem.getSpuId());
            }
            promotionDiscountPriceSearchParam.setSupplierNo(salesOrderItem.getSupplierNo());
            promotionDiscountPriceSearchParam.setEffectUntilDate(DateUtils.formatDate(salesOrderItem.getCreateTime()));
            promotionDiscountPriceSearchParam.setApplyDate(DateUtils.formatDate(salesOrderItem.getCreateTime()));
            materialSalesPriceSearchParam.setCustomerNo(salesOrderItem.getConsigneeId());
            materialSalesPriceSearchParam.setEffectUntilDate(salesOrderItem.getCreateTime());
            materialSalesPriceSearchParam.setApplyDate(salesOrderItem.getCreateTime());
            apamt= this.getSaleTotalDisctAmount(salesOrderItem, promotionDiscountPriceSearchParam,materialSalesPriceSearchParam);
        } else {
            //非活动正常销售
            materialSalesPriceSearchParam.setCustomerNo(salesOrderItem.getConsigneeId());
            if(!StringUtils.isNull(salesOrderItem.getGoodGroupId())){
                materialSalesPriceSearchParam.setGoodGroupId(salesOrderItem.getGoodGroupId());
            }else if(!StringUtils.isNull(salesOrderItem.getSkuId())){
                materialSalesPriceSearchParam.setSkuId(salesOrderItem.getSkuId());

            }else {
                materialSalesPriceSearchParam.setSpuId(salesOrderItem.getSpuId());
            }
            materialSalesPriceSearchParam.setEffectUntilDate(salesOrderItem.getCreateTime());
            materialSalesPriceSearchParam.setApplyDate(salesOrderItem.getCreateTime());
            apamt= this.getSaleTotalAmount(salesOrderItem, materialSalesPriceSearchParam);
            if(!StringUtils.isNull(salesOrderItem.getStoreDiscountCode())
                    &&salesOrderItem.getStoreDiscountCode()!="") {//搞活动
                if(salesOrderItem.getStoreDiscountAmt()!=null&&salesOrderItem.getStoreDiscountAmt()!=0.0){
                    apamt = NumberUtil.sub(apamt,salesOrderItem.getStoreDiscountAmt());
                }
                if(salesOrderItem.getStoreDiscountAmtPoint()!=null&&salesOrderItem.getStoreDiscountAmtPoint()!=0.0){
                    Double cnvertedAmt = this.convertMileToCash(salesOrderItem.getStoreDiscountAmtPoint());
                    apamt = NumberUtil.sub(apamt,cnvertedAmt);
                }
            }
        }
        // generateApList
        if(salesOrderItem.getMoney()==null||salesOrderItem.getMoney().doubleValue()==0.0){
            salesOrderItem.setMoney(apamt);
            SalesOrderItemSaveParam salesOrderItemSaveParam = new SalesOrderItemSaveParam();
            BeanUtils.copyProperties(salesOrderItem, salesOrderItemSaveParam);
            this.salesOrderItemService.update(salesOrderItem.getId(),salesOrderItemSaveParam);
            if(apamt==0.0){
                return apamt;
            }
        }else if(apamt==0.0){
            SalesOrderItemSaveParam salesOrderItemSaveParam = new SalesOrderItemSaveParam();
            BeanUtils.copyProperties(salesOrderItem, salesOrderItemSaveParam);
            this.salesOrderItemService.update(salesOrderItem.getId(), salesOrderItemSaveParam);
            return apamt;
        }

        String apgenerateResult = this.generateArList(apamt,salesOrderItem,userVo);
        return apamt;
    }
    @Override
    public double convertMileToCash(Double StoreDiscountAmtPoint){
        Double multi = new Double(0.05);
        double rt = NumberUtil.mul(StoreDiscountAmtPoint,multi);
        return rt;
    }
    /**
     * 生成财务应付数据
     * @param apamt
     * @param salesOrderItem
     * @return
     */
    @Override
    public String generateArList(Double apamt,SalesOrderItemVo salesOrderItem,UserVo userVo){
        AccountingAr accountingAp = new AccountingAr();
        Double unitAmt = NumberUtils.div(apamt.doubleValue(),salesOrderItem.getQty());
        accountingAp.setAmount(apamt);
        accountingAp.setBasicNo(salesOrderItem.getSalesOrderNo());
        accountingAp.setOrderItemNo(salesOrderItem.getId());
        if(!StringUtils.isNull(salesOrderItem.getSpuId()))
        {
            accountingAp.setCargoObjectName(salesOrderItem.getSpuName());
            accountingAp.setCargoObjectNo(salesOrderItem.getSpuId());
        }else{
            accountingAp.setCargoObjectName(salesOrderItem.getSkuName());
            accountingAp.setCargoObjectNo(salesOrderItem.getSkuId());
        }
        accountingAp.setOriginalCustName(salesOrderItem.getSupplierName());
        accountingAp.setPayCust(salesOrderItem.getSupplierNo());   // 付出去的 收款人
        accountingAp.setBillToCust(salesOrderItem.getMallBuyerNo()); // 付款人
        accountingAp.setPaiedFee(0.0);
        accountingAp.setConsigneeName(salesOrderItem.getConsigneeName());
        accountingAp.setContractAmount(apamt);
        accountingAp.setContractRate(unitAmt);
        accountingAp.setFrtCd("10001");
        accountingAp.setFrtNm("purchase");
        accountingAp.setInputType("A");
        accountingAp.setStatus(AccountingStatusEnum.CREATED.getStatus());
        accountingAp.setJobDate(DateUtils.formatDate(salesOrderItem.getCreateTime()));
        accountingAp.setOrderSeqNo(salesOrderItem.getSalesOrderId());
        accountingAp.setOriginalCustName(salesOrderItem.getMallBuyerNo());
        accountingAp.setRate(new BigDecimal(unitAmt));
        accountingAp.setRemainedAmount(apamt);
        accountingAp.setSite(userVo.getOrgId());
        accountingAp.setShipperName(salesOrderItem.getSupplierName());
        accountingAp.setSourceItemId(salesOrderItem.getId());
        accountingAp.setWtCnt(new BigDecimal(salesOrderItem.getQty()));
        return "success";
    }

    /**
     * 供应商对账减
     *
     * @param  accountingArSaveParam
     * @return
     */
    public String handleAdjustSub(AccountingArSaveParam accountingArSaveParam){
        return "success";
    }

    /**
     * 供应商对账减
     *
     * @param  accountingArSaveParam
     * @return
     */
    public String handleAdjustAdd(AccountingArSaveParam accountingArSaveParam){
        return "success";
    }
}
